package com.hzw.saas.service.rss.service;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzw.saas.api.rss.IJournalCatalogService;
import com.hzw.saas.api.rss.IJournalCatalogUserService;
import com.hzw.saas.api.rss.bo.JournalCatalogBO;
import com.hzw.saas.api.rss.bo.JournalCatalogUserBO;
import com.hzw.saas.api.user.IUserRightsService;
import com.hzw.saas.api.user.bo.UserRightsBO;
import com.hzw.saas.common.util.MapperUtil;
import com.hzw.saas.common.util.SnowFlakeUtil;
import com.hzw.saas.service.rss.mapper.*;
import com.hzw.saas.service.rss.model.JournalCatalogUser;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service("journalCatalogUserService")
public class JournalCatalogUserServiceImpl extends ServiceImpl<JournalCatalogUserMapper, JournalCatalogUser> implements IJournalCatalogUserService, IService<JournalCatalogUser> {


    @Autowired
    private IUserRightsService userRightsService;

    @Resource(name = "journalCatalogService")
    private IJournalCatalogService journalCatalogService;

    @Autowired
    private JournalCatalogUserMapper journalCatalogUserMapper;

    @Autowired
    private JournalCustomMapper journalCustomMapper;

    @Autowired
    private JournalUserSubMapper journalUserSubMapper;

    @Autowired
    private JournalUserActionMapper journalUserActionMapper;

    @Autowired
    private JournalUserAxisMapper journalUserAxisMapper;


    @Override
    public void addCatalogUser(List<JournalCatalogUserBO> catalogUsers, String userId) {
        ArrayList<JournalCatalogUser> journalCatalogUsers = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(catalogUsers)) {
            catalogUsers.forEach(s -> {
                JournalCatalogUser journalCatalogUser = new JournalCatalogUser();
                journalCatalogUser.setCatalogId(s.getCatalogId());
                journalCatalogUser.setCatalogName(s.getCatalogName());
                journalCatalogUser.setUserId(userId);
                String s1 = SnowFlakeUtil.nextIdStr();
                journalCatalogUser.setPid(s1);
                journalCatalogUsers.add(journalCatalogUser);
            });
            this.saveBatch(journalCatalogUsers);

            //刷新父节点
            List<String> collect = journalCatalogUsers.stream().map(JournalCatalogUser::getCatalogId).collect(Collectors.toList());
            List<JournalCatalogBO> byCatalogsWithTree = journalCatalogService.findByCatalogsWithTree(collect);
            HashMap<String, String> stringStringHashMap = new HashMap<>();
            ArrayList<JournalCatalogUser> journalCatalogUsers1 = new ArrayList<>();
            byCatalogsWithTree.forEach(journalCatalogBO -> {
                journalCatalogUsers.forEach(journalCatalogUser -> {
                    //找到相同的数据
                    if (journalCatalogBO.getPid().equals(journalCatalogUser.getCatalogId())) {
                        if (journalCatalogBO.getParentId().equals("0") || journalCatalogBO.getParentId() == null) {
                            journalCatalogUser.setParentId("0");
                            stringStringHashMap.put(journalCatalogBO.getPid(), journalCatalogUser.getPid());
                            journalCatalogUsers1.add(journalCatalogUser);
                        }
                    }
                });
            });

            updateBatchById(journalCatalogUsers1);
            journalCatalogUsers.removeAll(journalCatalogUsers1);
            //处理第二层级
            journalCatalogUsers.forEach(journalCatalogUser -> {
                byCatalogsWithTree.forEach(journalCatalogBO -> {
                    if (journalCatalogBO.getPid().equals(journalCatalogUser.getCatalogId())) {
                        journalCatalogUser.setParentId(journalCatalogBO.getParentId());
                    }
                });
            });

            journalCatalogUsers.forEach(journalCatalogUser -> {
                stringStringHashMap.forEach((k, v) -> {
                    if (journalCatalogUser.getParentId().equals(k)) {
                        journalCatalogUser.setParentId(v);
                    }
                });
            });
            if (CollectionUtil.isNotEmpty(journalCatalogUsers)) {
                updateBatchById(journalCatalogUsers);
            }

        }
    }

    private Boolean checkIsEdu(String email) {
        String edu = email.substring(email.length() - 7, email.length());
        String ac = email.substring(email.length() - 6, email.length());
        if (edu.equals("edu.com") || ac.equals("ac.com")) {
            return true;
        }
        return false;
    }

    @Override
    public List<JournalCatalogUserBO> getCatalogTreeByUserId(String userId) {
        List<JournalCatalogUser> list = this.lambdaQuery().eq(JournalCatalogUser::getUserId, userId).list();
        if (CollectionUtil.isEmpty(list)) {
            UserRightsBO userRightsByUser = userRightsService.getUserRightsByUser(userId);
            if (userRightsByUser != null && !userRightsByUser.getLevelId().equals("1")) {
                //没有数据，是手机或者edu/ac邮箱，新增数据
                List<JournalCatalogBO> publicCatalogIds = journalCatalogService.findPublicCatalogIds();
                ArrayList<JournalCatalogUserBO> journalCatalogUserBOS = new ArrayList<>();
                publicCatalogIds.forEach(journalCatalogBO -> {
                    JournalCatalogUserBO journalCatalogUserBO = new JournalCatalogUserBO();
                    journalCatalogUserBO.setUserId(userId);
                    journalCatalogUserBO.setCatalogId(journalCatalogBO.getPid());
                    journalCatalogUserBO.setCatalogName(journalCatalogBO.getName());
                    journalCatalogUserBOS.add(journalCatalogUserBO);
                });
                addCatalogUser(journalCatalogUserBOS, userId);
                return journalCatalogUserBOS;
            }
            List<JournalCatalogUserBO> journalCatalogUserBOS = MapperUtil.nt().mapAsList(list, JournalCatalogUserBO.class);
            return buildTree(journalCatalogUserBOS, "0");
        }
        List<JournalCatalogUserBO> journalCatalogUserBOS = MapperUtil.nt().mapAsList(list, JournalCatalogUserBO.class);
        return buildTree(journalCatalogUserBOS, "0");
    }


    @Override
    public List<JournalCatalogUserBO> findJournalCatalogUser(String userId) {
        List<JournalCatalogUser> list = this.lambdaQuery().eq(JournalCatalogUser::getUserId, userId).list();
        if (CollectionUtil.isEmpty(list)) {
            //没有数据，是手机或者edu/ac邮箱，新增数据
            List<JournalCatalogBO> publicCatalogIds = journalCatalogService.findPublicCatalogIds();
            ArrayList<JournalCatalogUserBO> journalCatalogUserBOS = new ArrayList<>();
            publicCatalogIds.forEach(journalCatalogBO -> {
                JournalCatalogUserBO journalCatalogUserBO = new JournalCatalogUserBO();
                journalCatalogUserBO.setUserId(userId);
                journalCatalogUserBO.setCatalogId(journalCatalogBO.getPid());
                journalCatalogUserBO.setCatalogName(journalCatalogBO.getName());
                journalCatalogUserBOS.add(journalCatalogUserBO);
            });
            addCatalogUser(journalCatalogUserBOS, userId);
            return MapperUtil.nt().mapAsList(publicCatalogIds, JournalCatalogUserBO.class);
        }
        return MapperUtil.nt().mapAsList(list, JournalCatalogUserBO.class);

    }

    @Override
    public void moveCatalogHeadNode(String pid, String newParent, String userId) {
        List<JournalCatalogUser> list = this.lambdaQuery().eq(JournalCatalogUser::getPid, pid).list();
        if (CollectionUtil.isNotEmpty(list)) {
            JournalCatalogUser journalCatalogUser = list.get(0);
            if (newParent.equals("0")) {
                journalCatalogUser.setParentId("0");
            } else {
                List<JournalCatalogUser> newNodes = this.lambdaQuery().eq(JournalCatalogUser::getPid, newParent).list();
                if (CollectionUtil.isNotEmpty(newNodes)) {
                    JournalCatalogUser node = newNodes.get(0);
                    if (node.getParentId() == null || !node.getParentId().equals("0")) {
                        throw new RuntimeException("分类最大层级不能超过2级");
                    }
                    journalCatalogUser.setParentId(newParent);
                }
            }
            updateById(journalCatalogUser);
        }

    }

    @Override
    public List<String> findAllUserCatalogIds() {
        List<JournalCatalogUser> list = this.lambdaQuery().list();
        if (CollectionUtil.isNotEmpty(list)) {
            return list.stream().map(JournalCatalogUser::getCatalogId).collect(Collectors.toList());
        }
        return null;
    }

    @Override
    public String findUserIdByCatalogId(String catalogId) {
        List<JournalCatalogUser> list = this.lambdaQuery().eq(JournalCatalogUser::getCatalogId, catalogId).list();
        if (CollectionUtil.isNotEmpty(list)) {
            return list.get(0).getUserId();
        }
        return null;
    }

    @Override
    public JournalCatalogUserBO findOne(String catalogId, String userId) {
        List<JournalCatalogUser> list = this.lambdaQuery().eq(JournalCatalogUser::getCatalogId, catalogId)
            .eq(JournalCatalogUser::getUserId, userId).list();
        if (CollectionUtil.isNotEmpty(list)) {
            JournalCatalogUser journalCatalogUser = list.get(0);
            return MapperUtil.nf().map(journalCatalogUser, JournalCatalogUserBO.class);
        }
        return null;
    }

    @Override
    public void recoveryCatalogUser(String userId) {
        List<JournalCatalogUser> list = this.lambdaQuery().eq(JournalCatalogUser::getUserId, userId).list();
        if (CollectionUtil.isNotEmpty(list)) {
            List<String> collect = list.stream().map(JournalCatalogUser::getPid).collect(Collectors.toList());
            journalCustomMapper.deleteByCatalogIds(collect);
        }
        journalCatalogUserMapper.deleteByUserId(userId);
        journalUserActionMapper.deleteByUserId(userId);
        journalUserSubMapper.deleteByUserId(userId);
        journalUserAxisMapper.deleteByUserId(userId);

        findJournalCatalogUser(userId);
    }

    @Override
    public void updateCatalogUser(JournalCatalogUserBO journalCatalogUserBO) {
        if (journalCatalogUserBO != null) {
            JournalCatalogUser byId = getById(journalCatalogUserBO.getPid());
            if (byId != null) {
                byId.setCatalogName(journalCatalogUserBO.getCatalogName());
                updateById(byId);
            }
        }
    }

    @Override
    public void deleteByHead(String pid) {
        journalCatalogUserMapper.deleteById(pid);
        journalCatalogUserMapper.deleteByParentId(pid);
    }

    @Override
    public void deleteCatalogUserTree(String pid) {
        List<JournalCatalogUser> list = this.lambdaQuery().eq(JournalCatalogUser::getPid, pid).list();
        if (CollectionUtil.isNotEmpty(list)) {
            JournalCatalogUser journalCatalogUser = list.get(0);
            journalCatalogUserMapper.deleteById(pid);
            if (journalCatalogUser != null) {
                journalCatalogUserMapper.deleteByParentId(pid);
            }
        }
    }

    @Override
    public JournalCatalogUserBO findById(String newCatalogId) {
        List<JournalCatalogUser> list = this.lambdaQuery().eq(JournalCatalogUser::getPid, newCatalogId).list();
        if (CollectionUtil.isNotEmpty(list)) {
            JournalCatalogUser journalCatalogUser = list.get(0);
            return MapperUtil.nf().map(journalCatalogUser, JournalCatalogUserBO.class);
        }
        return null;
    }

    @Override
    public List<String> findCatalogids(List<String> catalogIds) {
        List<JournalCatalogUser> list = this.lambdaQuery().in(JournalCatalogUser::getPid, catalogIds).list();
        if (CollectionUtil.isNotEmpty(list)) {
            return list.stream().map(JournalCatalogUser::getCatalogId).collect(Collectors.toList());
        }
        return Collections.emptyList();
    }

    @Override
    public List<JournalCatalogUserBO> findByIds(List<String> catalogs) {
        if (CollectionUtil.isNotEmpty(catalogs)) {
            List<JournalCatalogUser> list = this.lambdaQuery().in(JournalCatalogUser::getPid, catalogs).list();
            return MapperUtil.nt().mapAsList(list, JournalCatalogUserBO.class);
        }
        return Collections.emptyList();
    }

    @Override
    public List<JournalCatalogUserBO> finByUser(String userId) {
        List<JournalCatalogUser> list = this.lambdaQuery().eq(JournalCatalogUser::getUserId, userId)
            .list();
        if (CollectionUtil.isNotEmpty(list)) {
            return MapperUtil.nf().mapAsList(list, JournalCatalogUserBO.class);
        }
        return Collections.emptyList();
    }

    @Override
    public List<JournalCatalogUserBO> findByParent(String pid) {
        List<JournalCatalogUser> list = this.lambdaQuery().eq(JournalCatalogUser::getParentId, pid).list();
        if (CollectionUtil.isNotEmpty(list)) {
            return MapperUtil.nt().mapAsList(list, JournalCatalogUserBO.class);
        }
        return Collections.emptyList();
    }

    @Override
    public void updateBatch(List<JournalCatalogUserBO> byIds) {
        if (CollectionUtil.isNotEmpty(byIds)){
            this.updateBatchById(MapperUtil.nf().mapAsList(byIds,JournalCatalogUser.class));
        }
    }


    private static JournalCatalogUserBO findChildren(JournalCatalogUserBO treeNode, List<JournalCatalogUserBO> treeNodes) {
        for (JournalCatalogUserBO it : treeNodes) {
            if (treeNode.getPid().equals(it.getParentId())) {
                if (treeNode.getJournalCatalogUserBOS() == null) {
                    treeNode.setJournalCatalogUserBOS(new ArrayList<>());
                }
                treeNode.getJournalCatalogUserBOS().add(findChildren(it, treeNodes));
            }
        }
        return treeNode;
    }


    private static List<JournalCatalogUserBO> buildTree(List<JournalCatalogUserBO> treeNodes, String parentId) {
        List<JournalCatalogUserBO> trees = new ArrayList();
        for (JournalCatalogUserBO treeNode : treeNodes) {
            if (parentId.equals("0")) {
                if (parentId.equals(treeNode.getParentId())) {
                    trees.add(findChildren(treeNode, treeNodes));
                }
            } else {
                if (parentId.equals(treeNode.getPid())) {
                    trees.add(findChildren(treeNode, treeNodes));
                }
            }

        }
        return trees;
    }

}
